# coding:utf-8

import sys_utils
import tap_config
import data_container
import vsctl_handler
import ofctl_handler
import handler_manager
import traffic_collector

# 初始化数据容器实例
def init_data_container():
    return data_container.MainDataContainer()

# 初始化处理实体管理器
def init_handler_manager():
    data_container = init_data_container()
    return handler_manager.HandlerManager(data_container=data_container)

# 注册处理实体到处理实体管理器
def register_handlers(handler_manager):
    base_handler = vsctl_handler.VSCTLHandler(handler_manager.data_container)
    flow_handler = ofctl_handler.OFCTLHandler(handler_manager.data_container)
    handler_manager.add_cmd_handler("base", base_handler)
    handler_manager.add_cmd_handler("flow", flow_handler)

# 初始化流量统计线程
def init_traffic_collector(handler_manager):
    thread = traffic_collector.FlowTrafficCollectionThread(1059, "COLLECT_THREAD", handler_manager)
    thread.start()

# 获取PicOS中所有的端口信息，包括物理端口，LAG端口及其他类型端口
def fetch_ports_info(handler_manager):

    # 构造获取端口信息的命令行信息
    params = {}
    params['vsctl'] = tap_config.vsctl
    params['br_name'] = tap_config.bridge_name
    cmd_list_allports = tap_config.GET_ALL_PORTS_CMD.substitute(params)

    # 执行对应的命令行信息
    status, result, error = sys_utils.execute_cmd_line(cmd_list_allports)
    if status == -1:
        return

    ret_lines = result.splitlines()
    for line in ret_lines:
        parts = line.split('/')
        size = len(parts)

        # LAG端口、BOND端口等
        if size == 1 and line[0:2] == "ae":
            l = len(line)
            id = int(line[2:l])
            handler_manager.data_container.add_lagport(id, line)
            print '[INFO] LAG_PORT_ADD = <' + str(id) + '> ' + line

        # 物理端口
        if size >= 2:
            id = int(parts[2])
            handler_manager.data_container.add_phyport(id, line)
            print '[INFO] PHY_PORT_ADD = <' + str(id) + '> ' + line

# 从字符串中分析流表项信息
def parse_flowentry_string(string):
    '''
    flow_id=15, cookie=0x0, duration=20.209s, table=0, n_packets=n/a, n_bytes=0,
    priority=50000,ip,in_port=66,nw_dst=45.120.100.129 actions=set_field:48:6e:73:00:04:39->eth_dst,output:65
    '''
    flow_entry = data_container.FlowEntry()
    parts = string.split(' ')

    flow_part = parts[0]
    flow_parts = flow_part.split('=')
    flow_id = int(flow_parts[1][:-1])
    flow_entry.set_flow_id(flow_id)

    duration_part = parts[2]
    duration_parts = duration_part.split('=')
    duration = float(duration_parts[1][:-2])
    flow_entry.set_duration(duration)

    table_part = parts[3]
    table_parts = table_part.split('=')
    table = int(table_parts[1][:-1])
    flow_entry.set_table(table)

    match_field_part = parts[6]
    flow_entry.set_match_fields(match_field_part)

    action_part = parts[7]
    action_parts = action_part.split('=')
    actions = action_parts[1]
    flow_entry.set_actions(actions)

    return flow_entry

# 获取PicOS中所有的流表项信息
def fetch_flows_info(handler_manager):

    # 构造获取所有流表项的参数
    params = {}
    params['ofctl'] = tap_config.ofctl
    params['br_name'] = tap_config.bridge_name

    retcmd = tap_config.GET_FLOW_TABLE_CMD.substitute(params)

    # status: 0->success + -1->failure || result -> 返回结果 || error -> 返回错误
    status, result, error = sys_utils.execute_cmd_line(retcmd)

    if status == -1:
        return

    flowlines = result.splitlines()[1:]
    for line in flowlines:
        flow_entry = parse_flowentry_string(line.strip())
        handler_manager.data_container.add_flowentry(flow_entry.flow_id, flow_entry)